<template>
	<div class="middle">
		<div id="wrapper" class="wrapper" @mousedown="handleContainerMouseDown">
			<div id="content" class="content" ref="content" :style="contentStyle">
				<div class="container" id="container" ref="container" :style="containerStyle">
					<div class="grade" v-if="gradeFlag || contain.config.gradeShow" :style="gradeLenStyle"></div>
					<subgroup ref="subgroup" :nav="compsList" :subScale="wscale"></subgroup>
					<!-- 选中区域 -->
					<Area :start="area.start" :width="area.width" :height="area.height" :class="[area.isShowArea ? 'isShow' : '']" v-show="area.isShowArea" />
				</div>
			</div>
			<div class="page-bottom" v-if="isBuild">
				<div class="kp-operation">
					<el-slider v-model="plottscale" input-size="mini" show-input :min="0.15" :step="0.01" :max="2" @input="handlePlottScale"> </el-slider>
				</div>
			</div>
		</div>

		<wechat ref="wechat"></wechat>
	</div>
</template>

<script>
import wechat from '@/page/wechat/';
import subgroup from './subgroup';
import Area from '@/page/group/Area.vue';
import { config as defaultConfig } from '@/option/config';
import { getObj } from '@/api/visual';
import { website } from '@/config.js';
import { mapState, mapGetters } from 'vuex';
import common from '@/config';
import Vue from 'vue';

Vue.prototype.$website = website;
export default {
	name: 'contents',
	inject: ['contain'],
	props: {
		option: Object,
		id: [String, Number],
		wscale: Number
	},
	provide() {
		return {
			contain: this.contain,
			container: this
		};
	},
	components: {
		subgroup,
		wechat,
		Area
	},
	watch: {
		activeCompsIndex: {
			handler(value) {
				if (value && value.length > 0) {
					this.$refs.subgroup.setCompsActive(value);
					// 设置选中组件
				}
			}
		}
	},
	data() {
		return {
			common: common,
			area: {
				editorX: 0,
				editorY: 0,
				// 选中区域的起点
				start: {
					x: 0,
					y: 0
				},
				width: 0,
				height: 0,
				isShowArea: false
			},
			plottscale: 0.79,
			contentStyle: {},
			selectCount: {
				x1: null,
				x2: null,
				y1: null,
				y2: null
			},
			scale: 1,
			gradeFlag: false
		};
	},
	computed: {
		...mapState({
			globalEventList: state => state.event.globalEventList,
			activeComps: state => state.activeComps,
			compsList: state => state.compsList,
			areaData: state => state.areaData
		}),
		...mapGetters(['activeCompsIndex']),
		stepScale() {
			return Number(100 / this.scale);
			// let scale = Number(100 / (this.scale * this.wscale)).toFixed(2);
			// return scale;
		},
		//计算中央编辑区域比例
		containerStyle() {
			// this.setScale();
			const scale = this.contain.config.scale;
			let zoomModel = this.contain.config.zoomModel;
			const widthVal = scale / 100;
			const heightVal = document.body.clientHeight / this.contain.config.height - 0.002;
			let originStyle = {
				width: this.setPx(this.contain.config.width),
				height: this.setPx(this.contain.config.height),
				backgroundColor: this.contain.config.backgroundColor
			};
			if (!this.isBuild) {
				if (zoomModel == '2') {
					originStyle.postion = 'relative';
					originStyle.top = '50%';
					originStyle.left = 0;
				}
				if (zoomModel == '3') {
					originStyle.postion = 'relative';
					originStyle.top = 0;
					originStyle.left = '50%';
				}
			} else {
				//编辑页满足X
				originStyle.left = 0;
				originStyle.top = 0;
			}
			return Object.assign(
				originStyle,
				(() => {
					if (this.contain.config.backgroundImage) {
						return {
							background: `url(${this.contain.config.backgroundImage}) 0% 0% / 100% 100% rgb(3, 12, 59)`
						};
					}
					return;
				})()
			);
		},
		gradeLenStyle() {
			return {
				backgroundSize: `${this.setPx(this.contain.config.gradeLen)} ${this.setPx(this.contain.config.gradeLen)},${this.setPx(this.contain.config.gradeLen)} ${this.setPx(
					this.contain.config.gradeLen
				)}`
			};
		},
		isBuild() {
			return this.$route ? this.$route.name === 'build' : false;
		}
	},
	mounted() {
		// this.$refs.wechat.show()
		const that = this;
		that.initData();
		that.initFun();
		window.onresize = () => that.setScale();
	},
	beforeDestroy() {
		window.onresize = null;
	},
	methods: {
		initFun() {
			['handleRefresh', 'getDragObj'].forEach(ele => {
				this[ele] = this.$refs.subgroup[ele];
			});
		},
		initSnapData(snapDetail, snapData) {
			this.$store.commit('clearAllCompsList');
			const loading = this.$loading({
				lock: true,
				text: '正在加载中，请稍后',
				spinner: 'el-icon-loading',
				background: 'rgba(0, 0, 0, 0.7)'
			});
			this.contain.config = Object.assign({}, defaultConfig, snapDetail);
			this.$store.commit('setCanvasCompsList', snapData);
			loading.close();
		},
		//初始化数据
		initData() {
			const id = this.$route ? this.$route.params.id : this.id; // 看板id
			// const siteId = this.$route.query.siteId;
			// const tenantId = this.$route.query.tenantId;
			// const userId = this.$route.query.userId;
			this.contain.id = id;
			this.contain.contentWidth = this.$refs.content.offsetWidth;
			const width = this.isBuild ? this.contain.contentWidth : document.body.clientWidth;
			let config;
			const callback = () => {
				//赋值属性
				let mark = this.contain.config.mark;
				if (mark.show && !this.isBuild) {
					this.watermark(
						Object.assign(mark, {
							fontSize: mark.fontSize + 'px'
						})
					);
				}
				this.calcData();
				this.setScale();
			};
			if (id) {
				const loading = this.$loading({
					lock: true,
					text: '正在加载中，请稍后',
					spinner: 'el-icon-loading',
					background: 'rgba(0, 0, 0, 0.7)'
				});
				// getObj(id, siteId, tenantId, userId)
				getObj(id)
					.then(res => {
						const data = res.data.data;
						this.contain.obj = data;
						config = data.config;
						const contain = {
							config: JSON.parse(config.detail) || {},
							component: JSON.parse(config.component) || []
						};
						this.contain.config = Object.assign({}, defaultConfig, contain.config);

						if (this.contain.config && this.contain.config.scale) {
							this.plottscale = parseFloat((this.contain.config.scale / 100).toFixed(2));
							this.$emit('getPlottscale', this.plottscale);
						}

						this.contain.visual = data.visual;

						this.$store.dispatch('SetCanvasCompsListAsync', contain.component);

						// 设置全局请求头
						this.$store.dispatch('SetGlobalHeaderAsync', this.contain.config.header);

						// 设置全局参数
						this.$store.dispatch('SetGlobalVariableAsync', this.contain.config.variables);

						// vuex 中初始化事件集合
						this.initGlobalEventStore(this.compsList);

						document.title = this.$website.title + '-' + data.visual.title;

						//添加水印。只有查看页面生效
						if (!this.isBuild) {
							console.log('this.contain.visual', this.contain.visual);
							const password = this.contain.visual.password;
							if (!this.validatenull(password)) {
								this.$prompt('请输入密码', '提示', {
									confirmButtonText: '确定',
									showCancelButton: false,
									showClose: false,
									closeOnClickModal: false,
									inputPattern: new RegExp(password),
									inputErrorMessage: '密码不正确，请重新输入'
								}).then(() => {
									callback();
								});
							} else {
								callback();
							}
						} else {
							callback();
						}
						loading.close();
					})
					.catch(err => {
						console.log(err);
						loading.close();
					});
			} else if (this.option) {
				config = this.option;
				this.contain.config = config.detail || {};
				this.contain.nav = config.component || [];
				callback();
			} else {
				this.setScale();
			}
		},
		initGlobalEventStore(data) {
			let eventData = [];
			let compEventLists = data.filter(d => d.eventConfig);
			for (let i = 0; i < compEventLists.length; i++) {
				let eventList = compEventLists[i].eventConfig;
				if (eventList.length > 0) {
					for (let j = 0; j < eventList.length; j++) {
						if (eventList[j].status) {
							eventData.push(eventList[j]);
						}
					}
				}
			}
			this.$store.commit('event/registerEvent', eventData); // 注册组件事件
		},
		//计算比例
		setScale() {
			const designDraftWidth = this.contain.config.width; //设计稿的宽度
			const designDraftHeight = this.contain.config.height; //设计稿的高度
			let zoomModel = this.contain.config.zoomModel;
			this.setResize();
			// 根据屏幕的变化适配的比例
			let scaleX = document.documentElement.clientWidth / designDraftWidth;

			let scaleY = document.documentElement.clientHeight / designDraftHeight;

			this.contain.config.scale = Math.min(scaleX, scaleY) * 100;
			this.scale = this.contain.config.scale;
			if (!this.isBuild) {
				switch (zoomModel) {
					case '1':
						document.querySelector('#container').style.transform = `scale(${scaleX},${scaleY})`;
						break;

					case '2':
						document.querySelector('#container').style.transform = `scale(${scaleX}) translateY(-50%)`;
						this.contain.config.scale = scaleX * 100;
						this.scale = this.contain.config.scale;
						break;
					case '3':
						document.querySelector('#container').style.transform = `scale(${scaleY})  translateX(-50%)`;
						this.contain.config.scale = scaleY * 100;
						this.scale = this.contain.config.scale;
						break;
					case '4':
						break;
				}
			} else {
				const translateDistance = parseFloat(300 * (1 - this.plottscale).toFixed(2));
				document.querySelector('#container').style.transform = `translate(${translateDistance}px, ${translateDistance}px) scale(${this.plottscale})`;
			}
		},
		//适配尺寸
		setResize() {
			if (!this.isBuild) {
				this.contentStyle = {
					width: '100%',
					height: '100%',
					overflow: 'hidden'
				};
			} else {
				this.contentStyle = {
					width: '100%',
					height: '100%',
					overflow: 'hidden'
				};
			}
		},
		calcData() {
			if (!this.contain.config.mark) this.contain.config.mark = {};
			if (!this.contain.config.query) this.contain.config.query = {};
		},
		handlePostionSelect(postion) {
			this.handleCalcPostionSelect();
			const x1 = this.selectCount.x1;
			const x2 = this.selectCount.x2;
			const y1 = this.selectCount.y1;
			const y2 = this.selectCount.y2;
			if (postion === 'left') {
				this.handleMoveSelectList(x1, undefined, true, postion);
				// return false;
			} else if (postion === 'center') {
				this.handleMoveSelectList(x1 + (x2 - x1) / 2, undefined, true, postion);
			} else if (postion === 'right') {
				this.handleMoveSelectList(x2, undefined, true, postion);
			} else if (postion === 'top') {
				this.handleMoveSelectList(undefined, y1, true, postion);
			} else if (postion === 'middle') {
				this.handleMoveSelectList(undefined, y1 + (y2 - y1) / 2, true, postion);
			} else if (postion === 'bottom') {
				this.handleMoveSelectList(undefined, y2, true, postion);
			}
		},
		handleMoveSelectList(left, top, type, postion) {
			const that = this;
			let canvasComps = JSON.parse(JSON.stringify(that.compsList));
			canvasComps.forEach(ele => {
				that.activeComps.forEach(actComp => {
					if (ele.index == actComp.index) {
						const act_component = actComp.component;
						console.log('act_component', act_component);
						//水平情况
						if (left) {
							let baseLeft = Number(type ? left : (ele.left + left).toFixed(2));
							if (postion === 'right') {
								baseLeft = baseLeft - act_component.width;
							} else if (postion === 'center') {
								const obj_center = ele.left + act_component.width / 2;
								baseLeft = ele.left + (left - obj_center);
							}
							ele.left = baseLeft;
						}
						//垂直情况
						if (top) {
							let baseTop = Number(type ? top : (ele.top + top).toFixed(2));
							if (postion === 'bottom') {
								baseTop = baseTop - act_component.height;
							} else if (postion === 'middle') {
								const obj_middle = ele.top + act_component.height / 2;
								baseTop = ele.top + (top - obj_middle);
							}
							ele.top = baseTop;
						}
					}
				});
			});
			this.$store.commit('clearAllCompsList');
			this.$store.commit('setCanvasCompsList', canvasComps);
		},
		//计算多选状态下的最大边界值
		handleCalcPostionSelect() {
			this.selectCount = {
				x1: null,
				x2: null,
				y1: null,
				y2: null
			};
			this.activeComps.forEach(ele => {
				ele = this.contain.findlist(ele.index);
				const left = ele.left;
				const top = ele.top;
				const width = ele.component.width;
				const height = ele.component.height;
				if (!this.selectCount.x1) {
					this.selectCount = {
						x1: left,
						x2: left + width,
						y1: top,
						y2: top + height
					};
				}
				if (this.selectCount.x1 > left) this.selectCount.x1 = left;
				if (this.selectCount.x2 < left + width) this.selectCount.x2 = left + width;
				if (this.selectCount.y1 > top) this.selectCount.y1 = top;
				if (this.selectCount.y2 < top + height) this.selectCount.y2 = top + height;
			});
		},
		handleContainerMouseDown(e) {
			// this.contain.handleMouseDown();
			if (this.isBuild) {
				if (e && e.target) {
					this.$refs.subgroup && this.$refs.subgroup.clearAllCompsActive();
					// this.activeComps.map((act) => {
					//     let refIndex = `${this.common.DEAFNAME}${act.index}`;
					//     if (
					//         refIndex &&
					//         this.$refs[refIndex] &&
					//         this.$refs[refIndex][0]
					//     ) {
					//         this.$refs[refIndex][0].setActive(false);
					//     }
					// });
					// this.$store.commit("clearActiveComps");
				}
				this.handleSubGroupMouseDown(e);
			}
		},

		handleSubGroupMouseDown(e) {
			// 如果没有选中组件 在画布上点击时调用 e.preventDefault() 防止触发 drop 事件
			if (this.activeComps.length > 0) {
				e.preventDefault();
				this.activeComps.map(act => {
					let refIndex = `${this.common.DEAFNAME}${act.index}`;
					if (refIndex && this.$refs[refIndex] && this.$refs[refIndex][0]) {
						this.$refs[refIndex][0].setActive(false);
					}
				});
			}
			this.$store.commit('clearActiveComps');

			this.hideArea();
			const rectInfo = document.querySelector('#wrapper #container').getBoundingClientRect();

			this.area.editorX = rectInfo.x;
			this.area.editorY = rectInfo.y;
			const startX = e.clientX;
			const startY = e.clientY;
			this.area.start.x = (startX - this.area.editorX) * this.stepScale;
			this.area.start.y = (startY - this.area.editorY) * this.stepScale;
			this.area.isShowArea = true;
			const move = moveEvent => {
				const curX = moveEvent.clientX;
				const curY = moveEvent.clientY;
				this.area.width = Math.abs((curX - startX) * this.stepScale);
				this.area.height = Math.abs((moveEvent.clientY - startY) * this.stepScale);
				if (curX < startX) {
					this.area.start.x = curX - this.area.editorX;
				}
				if (curY < startY) {
					this.area.start.y = curY - this.area.editorY;
				}
			};
			const up = e => {
				document.removeEventListener('mousemove', move);
				document.removeEventListener('mouseup', up);
				// 起始点和结束点相同时重置区域
				if (e.clientX == startX && e.clientY == startY) {
					this.hideArea();
					return;
				}
				this.createGroup();
			};

			document.addEventListener('mousemove', move);
			document.addEventListener('mouseup', up);
		},
		createGroup() {
			// 获取选中区域的组件数据
			const areaData = this.getSelectArea();
			// 圈选区域组件个数小于1个时隐藏Area组件
			if (areaData.length < 1) {
				this.hideArea();
				return;
			}
			// 根据选中区域和区域中每个组件的位移信息来创建 Group 组件
			// 要遍历选择区域的每个组件，获取它们的 left top right bottom 信息来进行比较
			let top = Infinity,
				left = Infinity;
			let right = -Infinity,
				bottom = -Infinity;
			areaData.forEach(comp => {
				let style = {};
				style.left = comp.left;
				style.top = comp.top;
				style.bottom = style.top + comp.component.height;
				style.right = style.left + comp.component.width;
				if (style.left < left) left = parseInt(style.left);
				if (style.top < top) top = parseInt(style.top);
				if (style.right > right) right = style.right;
				if (style.bottom > bottom) bottom = style.bottom;
				// this.contain.active.push(comp.index);
			});
			this.area.start.x = left;
			this.area.start.y = top;
			this.area.width = parseInt(right - left);
			this.area.height = parseInt(bottom - top);
			// 设置选中区域位移大小信息和区域内的组件数据
			this.$store.commit('setAreaData', {
				style: {
					left: this.area.start.x,
					top: this.area.start.y,
					width: this.area.width,
					height: this.area.height
				},
				isGroup: true,
				activeComps: areaData,
				components: areaData
			});
		},
		getSelectArea() {
			const result = [];
			// 区域起点坐标
			const { x, y } = this.area.start;
			// 计算所有的组件数据，判断是否在选中区域内
			this.compsList.forEach(comp => {
				// if (comp.isLock) return;
				if (comp.children) return;
				const {
					left,
					top,
					component: { width, height }
				} = comp;
				if (x <= left && y <= top && left + width <= x + this.area.width && top + height <= y + this.area.height) {
					result.push(comp);
				}
			});

			// 返回在选中区域内的所有组件
			return result;
		},
		hideArea() {
			this.area.isShowArea = false;
			this.area.width = 0;
			this.area.height = 0;
			this.$store.commit('setAreaData', {
				style: {
					left: 0,
					top: 0,
					width: 0,
					height: 0
				},
				components: []
			});
		},
		handleHideArea() {
			this.hideArea();
		},
		setSubCompsActive(compsIndex) {
			this.$refs.subgroup.setCompsActive(compsIndex);
		},
		handlePlottScale(value) {
			this.contain.config.scale = value * 100;
			this.scale = this.contain.config.scale;

			const translateDistance = parseFloat(300 * (1 - this.plottscale).toFixed(2));

			this.$emit('changeCanvasScale', value, translateDistance);

			document.querySelector('#container').style.transform = `translate(${translateDistance}px, ${translateDistance}px) scale(${value})`;
		}
	}
};
</script>

<style lang="scss">
@import '@/styles/echart.scss';
@import '@/styles/style.scss';
.build.views {
	.middle {
		height: 100vh;
	}
}
.middle {
	.wrapper {
		display: flex;
		flex-direction: column;
		justify-content: space-between;
		.content {
			height: calc(100vh - 40px - 50px);
			overflow: hidden;
			background-image: url(/img/canvas/bg-canvas.png);
		}
		.page-bottom {
			width: 100%;
			height: 50px;
			display: flex;
			justify-content: flex-end;
			align-items: center;
			padding: 0 30px;
			box-sizing: border-box;
			background-color: #242629;
			border-top: 1px solid #0b0b0b;
			.kp-operation {
				width: 300px;
			}
		}
	}
}
</style>
